package com.maodou.core.ui.components.textfield

import androidx.compose.runtime.*
import java.util.regex.Pattern

/**
 * 验证结果
 */
sealed class TextValidationResult {
    object Valid : TextValidationResult()
    data class Invalid(val message: String) : TextValidationResult()

    val isValid: Boolean
        get() = this is Valid

    val errorMessage: String?
        get() = if (this is Invalid) message else null
}

/**
 * 验证器接口
 */
fun interface Validator {
    fun validate(input: String): TextValidationResult
}

/**
 * 组合验证器
 */
class CompositeValidator(private val validators: List<Validator>) : Validator {
    override fun validate(input: String): TextValidationResult {
        validators.forEach { validator ->
            val result = validator.validate(input)
            if (!result.isValid) {
                return result
            }
        }
        return TextValidationResult.Valid
    }
}

/**
 * 条件验证器
 */
class ConditionalValidator(
    private val condition: (String) -> Boolean,
    private val validator: Validator
) : Validator {
    override fun validate(input: String): TextValidationResult {
        return if (condition(input)) {
            validator.validate(input)
        } else {
            TextValidationResult.Valid
        }
    }
}

/**
 * 预定义验证器
 */
object TextValidators {
    
    /**
     * 必填验证器
     */
    fun required(message: String = "此字段为必填项"): Validator {
        return Validator { input ->
            if (input.isBlank()) {
                TextValidationResult.Invalid(message)
            } else {
                TextValidationResult.Valid
            }
        }
    }
    
    /**
     * 最小长度验证器
     */
    fun minLength(length: Int, message: String? = null): Validator {
        return Validator { input ->
            if (input.length < length) {
                TextValidationResult.Invalid(
                    message ?: "最少需要 $length 个字符"
                )
            } else {
                TextValidationResult.Valid
            }
        }
    }
    
    /**
     * 最大长度验证器
     */
    fun maxLength(length: Int, message: String? = null): Validator {
        return Validator { input ->
            if (input.length > length) {
                TextValidationResult.Invalid(
                    message ?: "最多允许 $length 个字符"
                )
            } else {
                TextValidationResult.Valid
            }
        }
    }
    
    /**
     * 长度范围验证器
     */
    fun lengthRange(min: Int, max: Int, message: String? = null): Validator {
        return Validator { input ->
            when {
                input.length < min -> TextValidationResult.Invalid(
                    message ?: "长度不能少于 $min 个字符"
                )
                input.length > max -> TextValidationResult.Invalid(
                    message ?: "长度不能超过 $max 个字符"
                )
                else -> TextValidationResult.Valid
            }
        }
    }
    
    /**
     * 正则表达式验证器
     */
    fun regex(pattern: String, message: String): Validator {
        val compiledPattern = Pattern.compile(pattern)
        return Validator { input ->
            if (compiledPattern.matcher(input).matches()) {
                TextValidationResult.Valid
            } else {
                TextValidationResult.Invalid(message)
            }
        }
    }
    
    /**
     * 邮箱验证器
     */
    fun email(message: String = "请输入有效的邮箱地址"): Validator {
        val emailPattern = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$"
        return regex(emailPattern, message)
    }
    
    /**
     * 手机号验证器（中国大陆）
     */
    fun phoneNumber(message: String = "请输入有效的手机号码"): Validator {
        val phonePattern = "^1[3-9]\\d{9}$"
        return regex(phonePattern, message)
    }
    
    /**
     * 身份证号验证器（中国大陆）
     */
    fun idCard(message: String = "请输入有效的身份证号码"): Validator {
        return Validator { input ->
            if (isValidIdCard(input)) {
                TextValidationResult.Valid
            } else {
                TextValidationResult.Invalid(message)
            }
        }
    }
    
    /**
     * 银行卡号验证器（Luhn算法）
     */
    fun bankCard(message: String = "请输入有效的银行卡号"): Validator {
        return Validator { input ->
            val cleanInput = input.replace("\\s", "")
            if (isValidBankCard(cleanInput)) {
                TextValidationResult.Valid
            } else {
                TextValidationResult.Invalid(message)
            }
        }
    }
    
    /**
     * URL验证器
     */
    fun url(message: String = "请输入有效的网址"): Validator {
        val urlPattern = "^(https?|ftp)://[^\\s/$.?#].[^\\s]*$"
        return regex(urlPattern, message)
    }
    
    /**
     * 数字验证器
     */
    fun number(message: String = "请输入有效的数字"): Validator {
        return Validator { input ->
            if (input.toDoubleOrNull() != null) {
                TextValidationResult.Valid
            } else {
                TextValidationResult.Invalid(message)
            }
        }
    }
    
    /**
     * 整数验证器
     */
    fun integer(message: String = "请输入有效的整数"): Validator {
        return Validator { input ->
            if (input.toIntOrNull() != null) {
                TextValidationResult.Valid
            } else {
                TextValidationResult.Invalid(message)
            }
        }
    }
    
    /**
     * 数字范围验证器
     */
    fun numberRange(
        min: Double? = null,
        max: Double? = null,
        message: String? = null
    ): Validator {
        return Validator { input ->
            val number = input.toDoubleOrNull()
            when {
                number == null -> TextValidationResult.Invalid("请输入有效的数字")
                min != null && number < min -> TextValidationResult.Invalid(
                    message ?: "数值不能小于 $min"
                )
                max != null && number > max -> TextValidationResult.Invalid(
                    message ?: "数值不能大于 $max"
                )
                else -> TextValidationResult.Valid
            }
        }
    }
    
    /**
     * 密码强度验证器
     */
    fun passwordStrength(
        minLength: Int = 8,
        requireUppercase: Boolean = true,
        requireLowercase: Boolean = true,
        requireDigit: Boolean = true,
        requireSpecialChar: Boolean = true,
        message: String? = null
    ): Validator {
        return Validator { input ->
            val errors = mutableListOf<String>()
            
            if (input.length < minLength) {
                errors.add("至少 $minLength 个字符")
            }
            
            if (requireUppercase && !input.any { it.isUpperCase() }) {
                errors.add("包含大写字母")
            }
            
            if (requireLowercase && !input.any { it.isLowerCase() }) {
                errors.add("包含小写字母")
            }
            
            if (requireDigit && !input.any { it.isDigit() }) {
                errors.add("包含数字")
            }
            
            if (requireSpecialChar && !input.any { !it.isLetterOrDigit() }) {
                errors.add("包含特殊字符")
            }
            
            if (errors.isEmpty()) {
                TextValidationResult.Valid
            } else {
                TextValidationResult.Invalid(
                    message ?: "密码必须${errors.joinToString("、")}"
                )
            }
        }
    }
    
    /**
     * 确认密码验证器
     */
    fun confirmPassword(
        originalPassword: String,
        message: String = "两次输入的密码不一致"
    ): Validator {
        return Validator { input ->
            if (input == originalPassword) {
                TextValidationResult.Valid
            } else {
                TextValidationResult.Invalid(message)
            }
        }
    }
    
    /**
     * 用户名验证器
     */
    fun username(
        minLength: Int = 3,
        maxLength: Int = 20,
        message: String? = null
    ): Validator {
        val usernamePattern = "^[a-zA-Z0-9_]{$minLength,$maxLength}$"
        return regex(
            usernamePattern,
            message ?: "用户名只能包含字母、数字和下划线，长度为 $minLength-$maxLength 个字符"
        )
    }
    
    /**
     * 中文姓名验证器
     */
    fun chineseName(message: String = "请输入有效的中文姓名"): Validator {
        val chineseNamePattern = "^[\\u4e00-\\u9fa5]{2,10}$"
        return regex(chineseNamePattern, message)
    }
    
    /**
     * 价格验证器
     */
    fun price(
        minValue: Double = 0.0,
        maxValue: Double = Double.MAX_VALUE,
        decimalPlaces: Int = 2,
        message: String? = null
    ): Validator {
        return Validator { input ->
            val cleanInput = input.replace(",", "")
            val number = cleanInput.toDoubleOrNull()
            
            when {
                number == null -> TextValidationResult.Invalid("请输入有效的价格")
                number < minValue -> TextValidationResult.Invalid(
                    message ?: "价格不能小于 $minValue"
                )
                number > maxValue -> TextValidationResult.Invalid(
                    message ?: "价格不能大于 $maxValue"
                )
                cleanInput.contains(".") && 
                cleanInput.substringAfter(".").length > decimalPlaces ->
                    TextValidationResult.Invalid("小数位数不能超过 $decimalPlaces 位")
                else -> TextValidationResult.Valid
            }
        }
    }
    
    /**
     * 自定义验证器
     */
    fun custom(
        predicate: (String) -> Boolean,
        message: String
    ): Validator {
        return Validator { input ->
            if (predicate(input)) {
                TextValidationResult.Valid
            } else {
                TextValidationResult.Invalid(message)
            }
        }
    }
    
    /**
     * 组合多个验证器
     */
    fun combine(vararg validators: Validator): Validator {
        return CompositeValidator(validators.toList())
    }
    
    /**
     * 条件验证器
     */
    fun conditional(
        condition: (String) -> Boolean,
        validator: Validator
    ): Validator {
        return ConditionalValidator(condition, validator)
    }
}

/**
 * 验证状态管理
 */
@Composable
fun rememberValidationState(
    initialValue: String = "",
    validator: Validator? = null
): ValidationState {
    return remember {
        ValidationState(initialValue, validator)
    }
}

/**
 * 验证状态类
 */
class ValidationState(
    initialValue: String = "",
    private val validator: Validator? = null
) {
    var value by mutableStateOf(initialValue)
        private set
    
    var validationResult by mutableStateOf<TextValidationResult?>(null)
        private set
    
    var hasBeenValidated by mutableStateOf(false)
        private set
    
    val isValid: Boolean
        get() = validationResult?.isValid ?: true
    
    val errorMessage: String?
        get() = validationResult?.errorMessage
    
    val showError: Boolean
        get() = hasBeenValidated && !isValid
    
    fun updateValue(newValue: String) {
        value = newValue
        validate()
    }
    
    fun validate(): TextValidationResult {
        hasBeenValidated = true
        validationResult = validator?.validate(value) ?: TextValidationResult.Valid
        return validationResult!!
    }
    
    fun clearValidation() {
        hasBeenValidated = false
        validationResult = null
    }
    
    fun reset(newValue: String = "") {
        value = newValue
        hasBeenValidated = false
        validationResult = null
    }
}

/**
 * 表单验证状态管理
 */
@Composable
fun rememberFormValidationState(
    fields: Map<String, Validator>
): FormValidationState {
    return remember {
        FormValidationState(fields)
    }
}

/**
 * 表单验证状态类
 */
class FormValidationState(
    private val fieldValidators: Map<String, Validator>
) {
    private val fieldStates = mutableMapOf<String, ValidationState>()
    
    var isValid by mutableStateOf(true)
        private set
    
    fun getFieldState(fieldName: String): ValidationState {
        return fieldStates.getOrPut(fieldName) {
            ValidationState(validator = fieldValidators[fieldName])
        }
    }
    
    fun validateAll(): Boolean {
        var allValid = true
        fieldStates.values.forEach { state ->
            val result = state.validate()
            if (!result.isValid) {
                allValid = false
            }
        }
        isValid = allValid
        return allValid
    }
    
    fun clearAllValidation() {
        fieldStates.values.forEach { it.clearValidation() }
        isValid = true
    }
    
    fun resetAll() {
        fieldStates.values.forEach { it.reset() }
        isValid = true
    }
    
    fun getFieldValue(fieldName: String): String {
        return getFieldState(fieldName).value
    }
    
    fun setFieldValue(fieldName: String, value: String) {
        getFieldState(fieldName).updateValue(value)
        updateFormValidation()
    }
    
    private fun updateFormValidation() {
        isValid = fieldStates.values.all { it.isValid }
    }
}

/**
 * 身份证号验证辅助函数
 */
private fun isValidIdCard(idCard: String): Boolean {
    if (idCard.length != 18) return false
    
    val weights = intArrayOf(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2)
    val checkCodes = charArrayOf('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2')
    
    var sum = 0
    for (i in 0..16) {
        val digit = idCard[i].toString().toIntOrNull() ?: return false
        sum += digit * weights[i]
    }
    
    val checkCode = checkCodes[sum % 11]
    return idCard[17] == checkCode
}

/**
 * 银行卡号验证辅助函数（Luhn算法）
 */
private fun isValidBankCard(cardNumber: String): Boolean {
    if (cardNumber.length < 13 || cardNumber.length > 19) return false
    if (!cardNumber.all { it.isDigit() }) return false
    
    var sum = 0
    var alternate = false
    
    for (i in cardNumber.length - 1 downTo 0) {
        var digit = cardNumber[i].toString().toInt()
        
        if (alternate) {
            digit *= 2
            if (digit > 9) {
                digit = digit / 10 + digit % 10
            }
        }
        
        sum += digit
        alternate = !alternate
    }
    
    return sum % 10 == 0
}